﻿// 版权所有 谈少民 2011  此代码由谈少民编写，享有完全的版权。tansm@msn.com 
// 2011-1-29 创建
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.Concurrent;

namespace System.Erp.Runtime
{
    /// <summary>
    /// 用于描述一个对象类型，相当于一个虚拟的对象类型，例如销售订单可以对应到SaleOrder
    /// </summary>
    /// <remarks>
    /// 此类设计的目的是加快对象类型的比较速度以及减少内存的占用。
    /// </remarks>
    [Serializable]
    public sealed class TypeKey : ConstString<TypeKey>
    {
        private static readonly ConcurrentDictionary<string, TypeKey> _dict;

        static TypeKey()
        {
            _global = new TypeKey(string.Empty);
            _dict = new ConcurrentDictionary<string, TypeKey>();
            _dict.TryAdd(string.Empty, _global);
        }

        private TypeKey(string typeKey)
            :base(typeKey)
        {}

        /// <summary>
        /// 获取一个指定字符串对应的TypeKey对象
        /// </summary>
        /// <param name="strTypeKey">类型字符串</param>
        /// <returns>对应的TypeKey实例</returns>
        public static TypeKey GetTypeKey(string strTypeKey)
        {
            strTypeKey = strTypeKey ?? string.Empty;
            return _dict.GetOrAdd(strTypeKey, (k) => new TypeKey(k));
        }

        /// <summary>
        /// 返回是否是全局对象键
        /// </summary>
        public bool IsGlobal
        {
            get { return this.StringValue == string.Empty; }
        }

        private readonly static TypeKey _global;
        /// <summary>
        /// 返回全局对象键。
        /// </summary>
        public TypeKey Global
        {
            get { return _global; }
        }

        #region 相等判断处理
        /// <summary>
        /// 返回两个对象键是否相等
        /// </summary>
        /// <param name="a">要判断的对象</param>
        /// <param name="b">要判断的对象</param>
        /// <returns>如果对象相等返回true，否则返回false</returns>
        public static bool operator ==(TypeKey a, TypeKey b)
        {
            return Equals(a, b);
        }

        /// <summary>
        /// 返回两个对象键是否不相等
        /// </summary>
        /// <param name="a">要判断的对象</param>
        /// <param name="b">要判断的对象</param>
        /// <returns>如果对象不相等返回true，否则返回false</returns>
        public static bool operator !=(TypeKey a, TypeKey b)
        {
            return !Equals(a, b);
        }

        /// <summary>
        /// 自定义的相等判断
        /// </summary>
        /// <param name="obj">要判断相等的对象</param>
        /// <returns>返回是否相等。</returns>
        public override bool Equals(object obj)
        {
            TypeKey other = obj as TypeKey;
            return (other == null) ? false : Equals(this, other);
        }

        /// <summary>
        /// 返回此对象的Hashcode，为类型字符串的hashcode.
        /// </summary>
        /// <returns>Hashcode的值。</returns>
        public override int GetHashCode()
        {
            return base.GetHashCode();
        }

        /// <summary>
        /// 支持从字符串隐式转换为此对象键
        /// </summary>
        /// <param name="str">要转换的字符串</param>
        /// <returns>对应的对象键</returns>
        public static implicit operator TypeKey(string str)
        {
            return GetTypeKey(str);
        }
        #endregion
    }
}
